#include <websocketpp.hpp>
#include <ConnectionBroker/Application.h>
#include <ConnectionBroker/Packet.h>
#include <ConnectionBroker/ServerSettings.h>

#include <boost/bind.hpp>
#include <boost/random/random_device.hpp>
#include <boost/random/uniform_int_distribution.hpp>

#include <stdlib.h>
#include <iostream>
#include <json/json.h>

using namespace ConnectionBroker;
int numMessages = 0;
void testCallback(ApplicationPtr pApp, ServerPtr pServer, ClientConnectionPtr pClient, const Packet& pMessage)
{
   std::cout << "pApp      = " << pApp << std::endl;
   std::cout << "pServer   = " << pServer << std::endl;
   std::cout << "pClient   = " << pClient << std::endl;
   std::cout << "pChannel  = " << pMessage.channel() << std::endl;
   std::cout << "pMessage  = " << pMessage.message() << std::endl;
   std::string msgStr("");
   std::string alphaNum("0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz");

   boost::random::random_device rng;
   boost::random::uniform_int_distribution<> fivethousand(0, 5000);
   int count = fivethousand(rng);
      boost::random::uniform_int_distribution<> index_dist(0, alphaNum.size() - 1);
   
   std::string str;
   count = 20000;
   for(int i = 0; i < count; ++i)
      str.append(1, alphaNum[index_dist(rng)]);
   
   Json::Value json(Json::objectValue);
   json["random"] = str;
   Packet p(pMessage.channel(), json);
   pApp->writeToAll(p);
}

void jeffsChannelCallback(ApplicationPtr pApp, ServerPtr pServer, ClientConnectionPtr pClient, const Packet& pMessage)
{
   std::cout << "Jeff's channel callback" << std::endl;
   std::cout << "pApp      = " << pApp << std::endl;
   std::cout << "pServer   = " << pServer << std::endl;
   std::cout << "pClient   = " << pClient << std::endl;
   std::cout << "pChannel  = " << pMessage.channel() << std::endl;
   std::cout << "pMessage  = " << pMessage.message() << std::endl;
   std::cout << "End Jeff's channel Callback" << std::endl;
}

void connectCallback(ApplicationPtr pApp, ServerPtr pServer, ClientConnectionPtr pClient, const Packet& pMessage)
{
}

int main()
{
   
   ApplicationPtr pApp(new Application());
   pApp->setSslInfo("ssl/server.crt", "ssl/server.key", "ssl/dh512.pem");
   
   ServerSettings settings1(9013);
   ServerSettings settings2(9014);
   ServerSettings settings3(9019);
   ServerSettings settings4(8919);
   ServerPtr pServer1(pApp->webSocketServerFactory(settings1));
   ServerPtr pServer2(pApp->tcpServerFactory(settings2));
   //ServerPtr pServer3(pApp->longPollServerFactory(settings3));
   ServerPtr pServer4(pApp->tcpServerFactory(settings4));
   pApp->setOnClientConnectCallback(boost::bind(&connectCallback, _1, _2, _3, _4));
   pApp->setOnMessageCallback(boost::bind(&testCallback, _1, _2, _3, _4));
   pApp->registerChannel("PM_HEARTBEAT_PUMP_ACCESS");
   pApp->registerChannel("PM_HEARTBEAT_PUMP_CREATE");
   pApp->registerChannel("PM_HEARTBEAT_PUMP_MODIFY");
   pApp->registerChannel("PM_HEARTBEAT_PUMP_DELETE");
   pApp->registerChannel("PM_HEARTBEAT_PUMP_OBSERVES");
   pApp->registerChannel("PM_HEARTBEAT_PUMP_BULK_EDIT");
   pApp->registerChannel("WORKFLOW_CLIENT_REQUEST");
   pApp->registerChannel("WORKFLOW_SERVER_BROADCAST");
   pApp->registerChannel("PM_HEARTBEAT_BATCH_REQUEST");
   pApp->registerChannel("PM_HEARTBEAT_BATCH_CLIENTS");
   pApp->registerChannel("PM_HEARTBEAT_BATCH_RESULT");
   pApp->registerChannel("PM_HEARTBEAT_BATCH_PROGRESS");

   while(true)
   {
      usleep(1000000);
   }
}
